package com.ruoyi.system.service.impl;

import java.util.*;

import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.uuid.Seq;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.domain.SysSerialMax;
import com.ruoyi.system.api.domain.SysSerial;
import com.ruoyi.system.api.domain.SysSerialConfig;
import com.ruoyi.system.api.domain.SysSerialOption;
import com.ruoyi.system.mapper.SysMapper;
import com.ruoyi.system.mapper.SysSerialConfigMapper;
import com.ruoyi.system.mapper.SysSerialMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.SysSerialMaxMapper;
import com.ruoyi.system.service.ISysSerialMaxService;

/**
 * 编号最大值Service业务层处理
 *
 * @author ruoyi
 * @date 2023-05-12
 */
@Service
public class SysSerialMaxServiceImpl implements ISysSerialMaxService
{
    private static final Logger log = LoggerFactory.getLogger(SysSerialMaxServiceImpl.class);

    @Autowired
    private SysSerialMaxMapper sysSerialMaxMapper;

    @Autowired
    private SysSerialConfigMapper sysSerialConfigMapper;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private SysSerialMapper sysSerialMapper;

    @Autowired
    private SysMapper sysMapper;

    /**
     * 查询编号最大值
     *
     * @param maxId 编号最大值主键
     * @return 编号最大值
     */
    @Override
    public SysSerialMax selectSysSerialMaxByMaxId(Long maxId)
    {
        return sysSerialMaxMapper.selectSysSerialMaxByMaxId(maxId);
    }

    /**
     * 查询编号最大值列表
     *
     * @param sysSerialMax 编号最大值
     * @return 编号最大值
     */
    @Override
    public List<SysSerialMax> selectSysSerialMaxList(SysSerialMax sysSerialMax)
    {
        return sysSerialMaxMapper.selectSysSerialMaxList(sysSerialMax);
    }

    @Override
    public SysSerialMax getNextValue(Map paramMap){
        int typeId = Integer.parseInt(paramMap.get("typeId").toString());
        SysSerial sysSerial = new SysSerial();
        sysSerial.setTypeId(typeId);
        List<SysSerial> sysSerialList = sysSerialMapper.selectSysSerialList(sysSerial);
        if(sysSerialList.size() == 0){
            return null;
        }
        sysSerial = sysSerialList.get(0);
        //当前编号可能引用了其它编号。
        if(sysSerial.getIsRel() == 1){
            Long relId = sysSerial.getRelId();
            sysSerial = sysSerialMapper.selectSysSerialBySerialId(relId);
            if(sysSerial == null){
                return null;
            }
            typeId = sysSerial.getTypeId();
        }else if(sysSerial.getIsRel() == 2 && paramMap.get("样品类别") != null){
            Long jclbId = Long.parseLong(String.valueOf(paramMap.get("样品类别")));
            if(jclbId.equals(1658880734024134621L)){
                typeId = 28;//土壤类
            }else if(jclbId.equals(1658880734024134618L) || jclbId.equals(1658880734024134619L) || jclbId.equals(1658880734024134620L)){
                typeId = 5;//气类
            }else {
                typeId = 6;//水类
            }
        }
        SysSerialConfig config = new SysSerialConfig();
        config.setTypeId(typeId);
        List<SysSerialConfig> configList = sysSerialConfigMapper.selectSysSerialConfigList(config);
        if(configList.size() == 0){
            throw new ServiceException("未查找到编辑配置信息！");
        }
        Long serialId = configList.get(0).getSerialId();
        List<SysSerialConfig> relConfigList = null;
        Map<Integer,String> ruleMap = new TreeMap<>();
        SysSerialConfig serialNo = null;
        for(SysSerialConfig config1 : configList){
            int configType = config1.getConfigType();
            int orderNum = config1.getOrderNum();
            switch (configType){
                case 0://固定字符
                    ruleMap.put(orderNum,config1.getConfigValue());
                    break;
                case 1://sql字段
                    String sql = StringUtils.getExecuteSql(config1.getConfigValue(),paramMap);
                    List<Map<String,Object>> optionMapList = sysMapper.select(sql);
                    String optionValue = null;
                    if(optionMapList.size() == 1){
                        ruleMap.put(orderNum,optionMapList.get(0).get("label").toString());
                        break;
                    }
                    if(paramMap.get(config1.getConfigId().toString()) != null){
                        optionValue = paramMap.get(config1.getConfigId().toString()).toString();
                    }
                    else{
                        optionValue = paramMap.get(config1.getConfigName()).toString();
                    }
                    String finalOptionValue = optionValue;
                    Map<String,Object> selectedOptionMap = optionMapList.stream().filter(o -> String.valueOf(o.get("value")).equals(finalOptionValue)).findFirst().orElse(null);
                    ruleMap.put(orderNum,(String)selectedOptionMap.get("label"));
                    break;
                case 2://自由字段
                    if(paramMap.get(config1.getConfigId().toString()) != null){
                        ruleMap.put(orderNum, paramMap.get(config1.getConfigId().toString()).toString());
                    }else if(paramMap.get(config1.getConfigName()) != null){
                        ruleMap.put(orderNum, paramMap.get(config1.getConfigName()).toString());
                    }
                    break;
                case 3://日期类型
                    if(paramMap.get(config1.getConfigId().toString()) != null){
                        ruleMap.put(orderNum, paramMap.get(config1.getConfigId().toString()).toString());
                    }else {
                        ruleMap.put(orderNum, DateUtils.parseDateToStr(config1.getConfigName(), new Date()));
                    }
                    break;
                case 4://选择字段
                    List<SysSerialOption> optionList = sysSerialConfigMapper.selectSysSerialConfigByConfigId(config1.getConfigId()).getSysSerialOptionList();
                    optionValue = null;
                    if(paramMap.get(config1.getConfigId().toString()) != null){
                        optionValue = paramMap.get(config1.getConfigId().toString()).toString();
                    }
                    else{
                        optionValue = paramMap.get(config1.getConfigName()).toString();
                    }
                    if(StringUtils.isEmpty(optionValue) || StringUtils.isEmpty(optionList)){
                        throw new ServiceException("查找选择字段值时出现错误，请联系管理员！");
                    }
                    finalOptionValue = optionValue;
                    SysSerialOption selectedOption = optionList.stream().filter(o -> o.getValue().equals(finalOptionValue) || o.getLabel().equals(finalOptionValue)).findFirst().orElse(null);
                    if(selectedOption == null){
                        throw new ServiceException("生成编号时未匹配到正确的值，请联系管理员！");
                    }
                    String labelValue = selectedOption.getValue();
                    if(config1.getMaxLength() != null && config1.getMaxLength() > labelValue.length()){//例如：最大长度为2位，labelvalue:7，则需要转化为07，如果labelValue:17,则不需要执行此条件。
                        try{
                            labelValue = StringUtils.padl(Integer.parseInt(selectedOption.getValue()),config1.getMaxLength());
                        }catch (NumberFormatException e){}
                    }
                    ruleMap.put(orderNum,labelValue);
                    break;
                case 6://参数字段
                    String paramValue = null;
                    if(StringUtils.isNotEmpty(paramMap)) {
                        if (paramMap.get(config1.getConfigId().toString()) != null) {
                            paramValue = paramMap.get(config1.getConfigId().toString()).toString();
                        } else if (paramMap.get(config1.getConfigName()) != null) {
                            paramValue = paramMap.get(config1.getConfigName()).toString();
                        }else{
                            paramValue = "";
                        }
                    }else{
                        paramValue = "";
                    }
                    ruleMap.put(orderNum,paramValue);
                    break;
                case 5://流水号
                    serialNo = config1;
                    break;
            }
            if(configType != 5 && config1.getAddZero() != null && config1.getAddZero() == 1){
                String paramValue = ruleMap.get(orderNum);
                if (StrUtil.isNotEmpty(paramValue)) {
                    try {
                        ruleMap.put(orderNum,StringUtils.padl(Integer.parseInt(paramValue), config1.getMaxLength()));
                    } catch (NumberFormatException var2) {
                    }
                }
            }
        }
        SysSerialMax sysSerialMax = null;
        //如果配置列表中有流水号字段则读取流水号生成规则
        if(serialNo != null) {
            config = new SysSerialConfig();
            config.getParams().put("dataScope", "and config_id in (" + serialNo.getRelConfigId() + ")");
            relConfigList = sysSerialConfigMapper.selectSysSerialConfigList(config);
            if(relConfigList.size() == 0){
                throw new ServiceException("未查找到流水号的引用字段！");
            }
            String conditionStr = "";
            if (StringUtils.isNotEmpty(relConfigList)) {
                for (SysSerialConfig config2 : relConfigList) {
                    conditionStr += "φ" + ruleMap.get(config2.getOrderNum());
                }
                conditionStr = conditionStr.substring(1);
                try {
                    sysSerialMax = jdbcTemplate.queryForObject("select * from sys_serial_max where org_id =? and serial_id = ? and `condition` = ? order by max_id desc limit 1", new BeanPropertyRowMapper<>(SysSerialMax.class), SecurityUtils.getOrgId(), serialId, conditionStr);
                    sysSerialMax.setMaxValue(sysSerialMax.getMaxValue() + 1);
                } catch (Exception e) {
                    log.error("未找到编号：" + serialId + "，条件：" + conditionStr + "，从1开始！");
                    sysSerialMax = new SysSerialMax();
                    sysSerialMax.setSerialId(serialId);
                    sysSerialMax.setCondition(conditionStr);
                    sysSerialMax.setMaxValue(1);
                }
                String strMaxValue;
                if(serialNo.getAddZero() == 1){
                    strMaxValue = StringUtils.padl(sysSerialMax.getMaxValue(), serialNo.getMaxLength());
                }else{
                    strMaxValue = sysSerialMax.getMaxValue().toString();
                }
                sysSerialMax.setStrMaxValue(strMaxValue);
                ruleMap.put(serialNo.getOrderNum(), strMaxValue);
            }
        }else{
            sysSerialMax = new SysSerialMax();
        }
        String maxCode = "";
        for (Map.Entry<Integer, String> entry : ruleMap.entrySet()) {
            maxCode += entry.getValue();
        }
        sysSerialMax.setMaxCode(maxCode);
        return sysSerialMax;
    }

    /**
     * 新增编号最大值
     *
     * @return 结果
     */
    @Override
    public SysSerialMax insertSysSerialMax(Map paramMap)
    {
        SysSerialMax sysSerialMax = getNextValue(paramMap);
        if(sysSerialMax == null) return sysSerialMax;
        sysSerialMax.setOrgId(SecurityUtils.getOrgId());
        if(sysSerialMax.getMaxId() != null){
            sysSerialMaxMapper.updateSysSerialMax(sysSerialMax);
        }
        else if(sysSerialMax.getSerialId() != null){//当前编号可能没有流水号
            sysSerialMax.setMaxId(Seq.getSeqId());
            sysSerialMaxMapper.insertSysSerialMax(sysSerialMax);
        }
        return sysSerialMax;
    }

    @Override
    public SysSerialMax insertSysSerialMaxBySerialId(int typeId)
    {
        Map dataMap = new HashMap();
        dataMap.put("typeId",typeId);
        SysSerialMax sysSerialMax = getNextValue(dataMap);
        if(sysSerialMax == null) return sysSerialMax;
        sysSerialMax.setOrgId(SecurityUtils.getOrgId());
        if(sysSerialMax.getMaxId() != null){
            sysSerialMaxMapper.updateSysSerialMax(sysSerialMax);
        }
        else{
            sysSerialMax.setMaxId(Seq.getSeqId());
            sysSerialMaxMapper.insertSysSerialMax(sysSerialMax);
        }
        return sysSerialMax;
    }

    /**
     * 批量删除编号最大值
     *
     * @param maxIds 需要删除的编号最大值主键
     * @return 结果
     */
    @Override
    public int deleteSysSerialMaxByMaxIds(Long[] maxIds)
    {
        return sysSerialMaxMapper.deleteSysSerialMaxByMaxIds(maxIds);
    }

    /**
     * 删除编号最大值信息
     *
     * @param maxId 编号最大值主键
     * @return 结果
     */
    @Override
    public int deleteSysSerialMaxByMaxId(Long maxId)
    {
        return sysSerialMaxMapper.deleteSysSerialMaxByMaxId(maxId);
    }
}
